object hanshu {
  def main(args: Array[String]): Unit = {
    //    def sayHi(name:String):Unit={
    //      println("hi,"+name)
    //    }
    //    //调用函数
    //    sayHi("yongguang")
    //    def f1(str:String*):Unit={
    //      println(str)
    //    }
    //    f1("aaa","bbbbd")
    //   f3("拉拉")
    //  }
    //  //函数返回值演示
    //  def f3(name:String)=name
    //  println(f3("可以省略花括号"))
    //
    // val fun= (name:String)=>{
    //    println("lambda表达式，匿名函数")
    //  }
    //fun("拉拉")
    def f(n:Int):Int={
      println("f函数调用")
      n+1//函数返回值
    }
    val result:Int=f(123)
    println(result)
    //函数可以作为值进行传递
    /**
     * val f1:Int=>Int=f _  //表示f1:Int是参数类型，=>后面是函数返回值类型，f(_)表示的是f这个函数
     * */
    val f1:Int=>Int=f(_)
    val f2 =f _
    println(f1)//打印函数是打印函数的地址
    println(f1(123))
    //调用函数体使用函数名加下划线，有返回值要返回返回值
    //调用函数相当于调用函数的地址，返回的是函数的地址对象
    //定义二元计算函数
    def dualEval(op:(Int,Int)=>Int,a:Int,b:Int):Int={
      println("将函数作为参数进行传递")
      op(a,b)
    }
    def add(a:Int,b:Int):Int={
      a+b
    }
    println(dualEval(add,12,12))
//函数作为函数的返回值返回（通过嵌套返回）
    def f5():Int=>Unit={
      def f6(a:Int):Unit={
        println("f6调用"+a)
      }
      f6(_)
    }
    val f6=f5()
    println("调用函数体对象"+f5())
    println("调用函数体对象"+f6(34))
    println("调用函数体对象"+f5()(55))


    println("========================================")
    //对数组进行处理，将操作抽象出来，处理完毕后返回一个新的数组
    val arr:Array[Int]=Array(12,13,16)
    def arrayOperation(array:Array[Int],op:Int=>Int):Array[Int]={
      for(elem <- array) yield  op(elem)
    }
    //定义一个op的加以函数操作
    def addOne(elem:Int):Int={
      return elem+1
    }
    //定义匿名函数，实现数据翻倍
    val newArray2=arrayOperation(arr,_*2)
    println(newArray2.mkString(","))
    //传递参数，传递函数操作，生成一个新的数组
    val newArray:Array[Int]=arrayOperation(arr,addOne(_))
    println(newArray.mkString(","))

    //调用匿名函数，返回false
    val fun=(i:Int,str:String,c:Char)=>{
      if(i==0&&str==""&&c=='0' ) false else true

    }
    println(fun(0,"",'0'))
    println(fun(1,"ff",'0'))
//嵌套循环调用函数，=>Int数据类型是传递给里面的函数
    def func(i:Int):String =>(Char=>Boolean)={
      def f1(s:String):Char =>Boolean ={
        def f2(c:Char):Boolean={
          if(i==0&&s==""&&c=='0') false else true
        }
        f2
      }
       f1
    }
    println("===========")
    println(func(0)("")('0'))
    println(func(5)("55")('0'))
    //函数循环嵌套匿名函数改写
    def func1(i:Int):String=>(Char=>Boolean)= {
      s => c => if (i == 0 && s == "" && c == '0') false else true
    }

        println(func1(0)("")('0'))
    //柯里化函数改写匿名函数
    /**
     * 柯里化函数：每个括号都是一层嵌套，括号里的是嵌套里的参数*/
    def func2(i:Int)(s:String)(c:Char):Boolean={
      if (i == 0 && s == "" && c == '0') false else true
    }
    println(func1(0)("")('0'))
    //lambaba表达式简写返回闭包
    def addByA(a:Int):Int=>Int={
      (b:Int)=>{
        a+b
      }
    }
    println("闭包函数返回的是："+addByA(23)(34))
//    println("闭包函数返回的是："+addByA(23))
//使用自定义的while循环
    val n=10
    //常规的while循环
    while(n>=1){
      println(n)
      n-1
    }
    //用闭包函数定义while函数

  }
}
